import React from 'react'
import PropTypes from 'prop-types'
import { bindActionCreators } from './varqins-redux'
export class Provider extends React.Component {
  static childContextTypes = {
    store: PropTypes.object
  }
  constructor(props, context) {
    super(props, context)
    this.store = props.store
  }
  getChildContext() {
    return {
      store: this.store
    }
  }
  render() {
    console.log(this.props.children)
    return this.props.children
  }
}
//connect 负责接收一个组件，将state的数据放进去，返回一个组件 connect(state, dispatch)(Component)
//数据变化的时候可以通知到组件

/* export function connect(){
  return function(Comp){
    return class WrapComponent extends React.Component{
      render(){
        return (
          <Comp></Comp>
        )
      }
    }
  }
} */

export const connect = (mapStateToProps, mapDispatchToProps) => (Comp) => {
  return class WrapComponent extends React.Component {
    static contextTypes = {
      store: PropTypes.object
    }
    constructor(props, context) {
      super(props, context)
      this.state = {
        props: {}
      }
    }
    componentDidMount() {
      const { store } = this.context
      store.subscribe(() => this.update())
      this.update()
    }
    update() {
      //获取mapStateToProps和mapDispatchToProps中的所有属性，作为组件的props传入子组件，这样在子组件中就可以直接使用this.props去掉用了
      const { store } = this.context
      const stateProps = mapStateToProps(store.getState())
      //数据可以直接给，方法不行因为需要dispatch
      //为了吧函数作为属性传入子组件，并且可以执行不能和数据一样直接传输，核心就是使用dispatch把action包一层,并且未执行，需要自己调用才行
      console.log(store.dispatch)
      //如果传入的值为一个简单对象，并未进行dispatch处理，则需要在函数内部进行二次处理
      debugger;
      const dispatchProps = bindActionCreators(mapDispatchToProps, store.dispatch)
      console.log(dispatchProps)
      //如果传入的mapDispatchToProps的值为：const mapDispatchToProps = (dispatch) => ({ _add(){dispatch(add())} })，则调用如下表达式即可，不需要再次传入
      //const dispatchProps = mapDispatchToProps(store.dispatch)
      this.setState({
        props: {
          ...this.state.props,
          ...stateProps,
          ...dispatchProps
        }
      })
    }
    render() {
      return (
        <Comp {...this.state.props}></Comp>
      )
    }
  }
}